﻿//
// Created by hujin on 2020/10/5.
//

#ifndef C_MIPS_CMPLR_AST_H
#define C_MIPS_CMPLR_AST_H

#include <string>
#include <vector>
#include <utility>
#include <map>
#include "../token.h"
#include "../symbolTable.h"
#include "../logger.h"
#include "../codegen/code_synthesis.h"
#include "../codegen/register.h"
#include "../codegen/mem_allocator.h"
#include "../analysis/var_indexer.h"
#include "../analysis/common_matcher.h"

class ASTNode {
protected:
	int line = 0, pos = 0;
public:
	int getLine() const {
		return line;
	}

	void setLine(int l) {
		this->line = l;
	}

	int getPos() const {
		return pos;
	}

	void setPos(int p) {
		this->pos = p;
	}

	void linkToTable(SymbolTable* table){
	    //this->symbolTable = table;
	}
	void logError(const std::string &s) const{
	    log_error(3, s, line, pos);
	}

	virtual void addToTable(SymbolTable* table) {};
    virtual bool checkError(SymbolTable* table) {return true;};
};
class ProgramNode; class CnstListNode; class CnstDefNode;
class IntNode; class FunctionHeadNode; class CnstNode;
class VarListNode; class VarDefNode; class VarDefInitNode;
class FunctionVoidNode; class FunctionNode; class BodyNode; class ParamsNode; class MainNode;
class ExprNode; class TermNode; class FactorNode;
class StatNode; class AssignNode; class IfNode; class ConditionNode;
class LoopNode;
class SwitchNode; class SwitchTableNode; class CaseNode; class DefalutNode;
class FuncCallNode; class VoidCallNode; class FuncCallParamsNode;
class StatListNode; class ScanfNode; class PrintfNode; class ReturnNode;

class IdentiferFactor; class FunctionCallFactor;


class ProgramNode : public  ASTNode {
	CnstListNode* cnsttable = nullptr;
	VarListNode* vardef = nullptr;
	std::vector<FunctionNode*> functions;
	MainNode* mainNode;
public:
	ProgramNode(CnstListNode* cnsttable, VarListNode* vardef, std::vector<FunctionNode*>& functions,
		MainNode* mainNode) : cnsttable(cnsttable), vardef(vardef), functions(std::move(functions)), mainNode(mainNode) {}

    void genCode(Synthesizer *out, MemoryAllocator *allocator) ;
};




class MainNode : public  ASTNode {

    BodyNode* statements;
public:
    explicit MainNode(BodyNode* statements) : statements(statements) {}
    void genCode(Synthesizer *out, MemoryAllocator *allocator) ;
};


#endif //C_MIPS_CMPLR_AST_H
